﻿#include <QObject>
#include <QDir>
#include <QTextCodec>
#include <QCoreApplication>
#include <QSettings>
#include <QFile>
#include <QStringList>
#include <QDebug>
//#include <QMessageBox>
#include "DirMgr.h"
#include "../qstring_ex/qstringex.h"


XCHAR** P_SYSTEM_DIR_EN_STR=NULL;

XBOOL IS_INIT=XFALSE;

QSharedMemory sharedMemory;

const QString SHARED_MEMORY_KEY="Dir_Mgr_Init";
const int DEFAULT_MEMORY_SIZE=10000;

DirMgr::DirMgr()
{
}

DirMgr::~DirMgr()
{
}

QString DirMgr::getdir(XUINT type)
{
	if (IS_INIT == XFALSE)
	{
		init(false);
	}

	XINT k=0;
	for(k;k<SYSTEM_DIR_NSA3000T_MAXCOUNT;k++)
	{
		if(SYSTEM_DIR_VAL[k]==type)
		{
			break;
		}
	}
	if (k<SYSTEM_DIR_NSA3000T_MAXCOUNT)
	{
		XString strPath=QCoreApplication::applicationDirPath();
		XString alldir="";
		QStringList splitdir=strPath.split("/");
		XINT i=0;
		for(i;i<splitdir.count();i++)
		{
			if(splitdir.at(i)==QStringEx::fromLocal8Bit(P_SYSTEM_DIR_EN_STR[0]))
			{
				break;
			}
		}
		for(XINT j=0;j<i;j++)
			alldir+=splitdir.at(j)+"/";
		if (k>0)
		{
			alldir+=QStringEx::fromLocal8Bit(P_SYSTEM_DIR_EN_STR[0])+"/";
		}
		alldir+=QStringEx::fromLocal8Bit(P_SYSTEM_DIR_EN_STR[k]);
		return alldir;
	}
	else return QStringEx::fromLocal8Bit("ALL");
}

XString DirMgr::GetSysDirCh_Name(XUINT dir_val)
{
	if (IS_INIT == XFALSE)
	{
		init(false);
	}
    XINT i=0;
    for(i;i<SYSTEM_DIR_NSA3000T_MAXCOUNT;i++)
    {
        if(SYSTEM_DIR_VAL[i]==dir_val)
        {
            break;
        }
    }
    if (i<SYSTEM_DIR_NSA3000T_MAXCOUNT)
    {
        return QStringEx::fromLocal8Bit(SYSTEM_DIR_CH_STR[i]);
    }
    else
		return QStringEx::fromLocal8Bit("全部");
}

XString DirMgr::GetSysDirEn_Name(XUINT dir_val)
{
	if (IS_INIT == XFALSE)
	{
		init(false);
	}

    XString en_name=getdir(dir_val);
    if(dir_val==SYSTEM_DIR_BIN||dir_val==SYSTEM_DIR_APP||dir_val==SYSTEM_DIR_COM||dir_val==SYSTEM_DIR_L_ZIP)
    {
		#ifdef CUR_RUN_SYS_WINDOWS_VS2008
			en_name=en_name+"/win";
		#endif
		#ifdef CUR_RUN_SYS_LINUX_QT
			en_name=en_name+"/lnx";
		#endif
    }
    else
	{
		#ifdef CUR_RUN_SYS_WINDOWS_VS2008
			en_name=en_name.replace("lnx","win");
		#endif
		#ifdef CUR_RUN_SYS_LINUX_QT
			en_name=en_name.replace("win","lnx");
		#endif
	}
    QStringList enname=en_name.split("/");
    en_name="";
    XINT i=0;
    for(i;i<enname.count();i++)
    {
		XCHAR root_name[100];
		memcpy(root_name,(XCHAR*)P_SYSTEM_DIR_EN_STR[0],SYSTEM_DIR_NSA3000T_STR_MAXCOUNT);
        if(enname.at(i)==QStringEx::fromLocal8Bit(root_name))
            break;
    }
    for(int j=i;j<enname.count();j++)
        en_name=en_name+enname.at(j)+"/";
    return en_name;
}

XString DirMgr::GetSysDirAllEn_Name(XUINT dir_val)
{
	if (IS_INIT == XFALSE)
	{
		init(false);
	}

	XString strPath=QCoreApplication::applicationDirPath();
	XString dir=GetSysDirEn_Name(dir_val);
    XString alldir="";
	QStringList splitdir=strPath.split("/");
	XINT i=0;
	for(i;i<splitdir.count();i++)
	{
		XCHAR root_name[100];
		memcpy(root_name,(XCHAR*)P_SYSTEM_DIR_EN_STR[0],SYSTEM_DIR_NSA3000T_STR_MAXCOUNT);
		if(splitdir.at(i)==QStringEx::fromLocal8Bit(root_name))
		{
			break;
		}
	}
	for(XINT j=0;j<i;j++)
		alldir+=splitdir.at(j)+"/";
	alldir+=dir;
	return alldir;
}

QString DirMgr::GetSysDirTrue_Name(XUINT type)
{
	if (IS_INIT == XFALSE)
	{
		init(false);
	}

	XINT k=0;
	for(k;k<SYSTEM_DIR_NSA3000T_MAXCOUNT;k++)
	{
		if(SYSTEM_DIR_VAL[k]==type)
		{
			break;
		}
	}
	if (k<SYSTEM_DIR_NSA3000T_MAXCOUNT)
	{
		return QStringEx::fromLocal8Bit(P_SYSTEM_DIR_EN_STR[k]);
	}
	else return QStringEx::fromLocal8Bit("ALL");
}

XINT DirMgr::CreateNSA3000TSysDir(XUINT dir_val)
{
	if (IS_INIT == XFALSE)
	{
		init(false);
	}
    XString dir=GetSysDirAllEn_Name(dir_val);
    if(!QDir(dir).exists())
    {
		QDir Dir;
		Dir.mkpath(dir);
	}
    return 1;
}

XVOID DirMgr::CreateAllNSA3000TSysDir()
{
	if (IS_INIT == XFALSE)
	{
		init(false);
	}
    for(XINT i=0;i<SYSTEM_DIR_NSA3000T_MAXCOUNT;i++)
    {
#ifdef CUR_RUN_SYS_WINDOWS_VS2008
		if ( i!=SYSTEM_DIR_BIN_LNX && i!=SYSTEM_DIR_APP_LNX && i!=SYSTEM_DIR_L_ZIP_LNX && i!=SYSTEM_DIR_COM_LNX)
		{
			XString dir=getdir(SYSTEM_DIR_VAL[i]);
			if(!QDir(dir).exists())
			{
				QDir makedir;
				makedir.mkpath(dir);
			}
		}
#endif
#ifdef CUR_RUN_SYS_LINUX_QT
		if ( i!=SYSTEM_DIR_BIN_WIN && i!=SYSTEM_DIR_APP_WIN && i!=SYSTEM_DIR_L_ZIP_WIN && i!=SYSTEM_DIR_COM_WIN)
		{
			XString dir=getdir(SYSTEM_DIR_VAL[i]);
			if(!QDir(dir).exists())
			{
				QDir makedir;
				makedir.mkpath(dir);
			}
		}
#endif
    }
}

XString DirMgr::GetSys_MM_SM_FILE_PATH()
{
	if (IS_INIT == XFALSE)
	{
		init(false);
	}
	XString rd_sm_file_dir=GetSysDirAllEn_Name(SYSTEM_DIR_SM_FILE);
	rd_sm_file_dir+=SYSTEM_SM_FILE_NAME_MM;
	return rd_sm_file_dir;
}

XString DirMgr::GetSys_RD_SM_FILE_PATH()
{
	if (IS_INIT == XFALSE)
	{
		init(false);
	}
    XString rd_sm_file_dir=GetSysDirAllEn_Name(SYSTEM_DIR_SM_FILE);
    rd_sm_file_dir+=SYSTEM_SM_FILE_NAME_RD;
    return rd_sm_file_dir;
}

XString DirMgr::GetSys_SS_SM_FILE_PATH()
{
	if (IS_INIT == XFALSE)
	{
		init(false);
	}
    XString ss_sm_file_dir=GetSysDirAllEn_Name(SYSTEM_DIR_SM_FILE);
    ss_sm_file_dir+=SYSTEM_SM_FILE_NAME_SS;
    return ss_sm_file_dir;
}

XString DirMgr::GetSys_DS_SM_FILE_PATH()
{
	if (IS_INIT == XFALSE)
	{
		init(false);
	}
    XString ds_sm_file_dir=GetSysDirAllEn_Name(SYSTEM_DIR_SM_FILE);
    ds_sm_file_dir+=SYSTEM_SM_FILE_NAME_DS;
    return ds_sm_file_dir;
}

XString DirMgr::GetSys_NM_SM_FILE_PATH()
{
	if (IS_INIT == XFALSE)
	{
		init(false);
		IS_INIT = XTRUE;
	}
    XString nm_sm_file_dir=GetSysDirAllEn_Name(SYSTEM_DIR_SM_FILE);
    nm_sm_file_dir+=SYSTEM_SM_FILE_NAME_NM;
    return nm_sm_file_dir;
}

XString DirMgr::GetSys_LM_SM_FILE_PATH()
{
	if (IS_INIT == XFALSE)
	{
		init(false);
	}
	XString nm_sm_file_dir=GetSysDirAllEn_Name(SYSTEM_DIR_SM_FILE);
        nm_sm_file_dir+=SYSTEM_SM_FILE_NAME_LM;
	return nm_sm_file_dir;
}

XString DirMgr::GetSys_RG_SM_FILE_PATH()
{
	if (IS_INIT == XFALSE)
	{
		init(false);
	}
	XString nm_sm_file_dir=GetSysDirAllEn_Name(SYSTEM_DIR_SM_FILE);
	nm_sm_file_dir+=SYSTEM_SM_FILE_NAME_RG;
	return nm_sm_file_dir;
}

int DirMgr::init(bool isForceRefresh)
{
	if (isForceRefresh)
	{
		IS_INIT = XFALSE;
	}
	if (IS_INIT == XTRUE)
	{
		return 0;
	}
	initializeMemory(isForceRefresh);

	IS_INIT = XTRUE;
	return 1;
}

void DirMgr::f_init()
{
	P_SYSTEM_DIR_EN_STR=NULL;

	IS_INIT = XFALSE;

	sharedMemory.lock();
	cleanMemory();
	sharedMemory.unlock();

	sharedMemory.detach();
}

void DirMgr::init_p_en_dir()
{
	P_SYSTEM_DIR_EN_STR=NULL;
	P_SYSTEM_DIR_EN_STR = new XCHAR*[SYSTEM_DIR_NSA3000T_MAXCOUNT];
	for(XINT i=0;i<SYSTEM_DIR_NSA3000T_MAXCOUNT;i++)
	{
		P_SYSTEM_DIR_EN_STR[i]=new XCHAR[SYSTEM_DIR_NSA3000T_STR_MAXCOUNT];
		memcpy(P_SYSTEM_DIR_EN_STR[i],SYSTEM_DIR_EN_STR[i],SYSTEM_DIR_NSA3000T_STR_MAXCOUNT);
	}
}

XBOOL DirMgr::read_cfg_file()
{
	XString strPath=QCoreApplication::applicationDirPath();
	XString FilePath="";
	XString RootPath="";
	QStringList splitdir=strPath.split("/");
	if (splitdir.count()<3)
	{
		return XFALSE;
	}
	for(XINT i=0;i<splitdir.count()-2;i++)
		FilePath+=splitdir.at(i)+"/";
	RootPath=splitdir.at(splitdir.count()-3);
	sprintf(P_SYSTEM_DIR_EN_STR[0],RootPath.toLocal8Bit().data());
	//QMessageBox::about(0,"1111",RootPath);

	FilePath+="sys_para/sys/dir_mgr.ini";

	QFile file(FilePath);
	if (!file.exists())
	{
		set_cfg_file();
	}
	else
	{
		QSettings settings(FilePath, QSettings::IniFormat);

		XString set_name_str="";
		XString set_value_str="";

		for (XINT j=1;j<SYSTEM_DIR_NSA3000T_MAXCOUNT;j++)
		{
			set_name_str="";
			set_value_str="";
			set_name_str="DirCfg/"+QStringEx::fromLocal8Bit(SYSTEM_DIR_VAL_NAME[j]);
			set_value_str=settings.value(set_name_str).toString();
			if (set_value_str!="")
			{
				if(SYSTEM_DIR_VAL[j]==SYSTEM_DIR_BIN_WIN||SYSTEM_DIR_VAL[j]==SYSTEM_DIR_BIN_LNX||SYSTEM_DIR_VAL[j]==SYSTEM_DIR_APP_WIN||SYSTEM_DIR_VAL[j]==SYSTEM_DIR_APP_LNX
					||SYSTEM_DIR_VAL[j]==SYSTEM_DIR_L_ZIP_WIN||SYSTEM_DIR_VAL[j]==SYSTEM_DIR_L_ZIP_LNX||SYSTEM_DIR_VAL[j]==SYSTEM_DIR_COM_WIN||SYSTEM_DIR_VAL[j]==SYSTEM_DIR_COM_LNX
					||SYSTEM_DIR_VAL[j]==SYSTEM_DIR_SYS_PARA||SYSTEM_DIR_VAL[j]==SYSTEM_DIR_SYS_PARA_61850||SYSTEM_DIR_VAL[j]==SYSTEM_DIR_SYS_PARA_SYS||SYSTEM_DIR_VAL[j]==SYSTEM_DIR_SYS_PARA_FILE
					||SYSTEM_DIR_VAL[j]==SYSTEM_DIR_SYS_PARA_GRAPH||SYSTEM_DIR_VAL[j]==SYSTEM_DIR_SYS_PARA_DSN||SYSTEM_DIR_VAL[j]==SYSTEM_DIR_SYS_PARA_OTHER||SYSTEM_DIR_VAL[j]==SYSTEM_DIR_SYS)
				{
					continue;
				}
				sprintf(P_SYSTEM_DIR_EN_STR[j],set_value_str.toLocal8Bit().data());
				if(SYSTEM_DIR_VAL[j]==SYSTEM_DIR_BIN||SYSTEM_DIR_VAL[j]==SYSTEM_DIR_APP||SYSTEM_DIR_VAL[j]==SYSTEM_DIR_COM||SYSTEM_DIR_VAL[j]==SYSTEM_DIR_L_ZIP)
				{
					QString set_value_str_temp1=set_value_str+"/win";
					sprintf(P_SYSTEM_DIR_EN_STR[j+1],set_value_str_temp1.toLocal8Bit().data());
					QString set_value_str_temp2=set_value_str+"/lnx";
					sprintf(P_SYSTEM_DIR_EN_STR[j+2],set_value_str_temp2.toLocal8Bit().data());
					j+=2;
				}
			}
		}
	}

	return XTRUE;
}

XBOOL DirMgr::set_cfg_file()
{
	XString strPath=QCoreApplication::applicationDirPath();
	XString FilePath="";
	XString RootPath="";
	QStringList splitdir=strPath.split("/");
	if (splitdir.count()<3)
	{
		return XFALSE;
	}
	for(XINT i=0;i<splitdir.count()-2;i++)
		FilePath+=splitdir.at(i)+"/";

	FilePath+="sys_para/sys/dir_mgr.ini";

	QSettings settings(FilePath, QSettings::IniFormat);

	XString set_name_str="";
	for (XINT j=1;j<SYSTEM_DIR_NSA3000T_MAXCOUNT;j++)
	{
		if(SYSTEM_DIR_VAL[j]==SYSTEM_DIR_SYS_PARA)
		{
			j+=6;
			continue;
		}
		set_name_str="DirCfg/"+QStringEx::fromLocal8Bit(SYSTEM_DIR_VAL_NAME[j]);
		settings.setValue(set_name_str,QStringEx::fromLocal8Bit(P_SYSTEM_DIR_EN_STR[j]));
		if(SYSTEM_DIR_VAL[j]==SYSTEM_DIR_BIN||SYSTEM_DIR_VAL[j]==SYSTEM_DIR_APP||SYSTEM_DIR_VAL[j]==SYSTEM_DIR_COM||SYSTEM_DIR_VAL[j]==SYSTEM_DIR_L_ZIP)
		{
			j+=2;
		}
	}
	
	return XTRUE;
}

void DirMgr::change_dir(XUINT dir_val,QString new_dir)
{
	if (IS_INIT == XFALSE)
	{
		init(false);
	}
	XINT i=0;
	for(i;i<SYSTEM_DIR_NSA3000T_MAXCOUNT;i++)
	{
		if(SYSTEM_DIR_VAL[i]==dir_val)
		{
			break;
		}
	}
	QString old_dir=QString::fromLocal8Bit(P_SYSTEM_DIR_EN_STR[i]);
	if(dir_val==SYSTEM_DIR_BIN||dir_val==SYSTEM_DIR_APP||dir_val==SYSTEM_DIR_COM||dir_val==SYSTEM_DIR_L_ZIP)
	{
		for(XINT j=i;j<i+3;j++)
		{
			QString old_dir_temp=QString::fromLocal8Bit(P_SYSTEM_DIR_EN_STR[j]);
			old_dir_temp.replace(old_dir,new_dir);
			sprintf(P_SYSTEM_DIR_EN_STR[j],old_dir_temp.toLocal8Bit().data());
		}
	}
	else
	{
		old_dir.replace(old_dir,new_dir);
		sprintf(P_SYSTEM_DIR_EN_STR[i],old_dir.toLocal8Bit().data());
	}
}

void DirMgr::initializeMemory(bool isForceRefresh)
{
	sharedMemory.setKey(SHARED_MEMORY_KEY);
	init_p_en_dir();

	if (sharedMemory.isAttached())
		sharedMemory.detach();

	if (!sharedMemory.attach(QSharedMemory::ReadWrite)) 
	{

		//QMessageBox::information(0,"Success",QString::number(1));
		// Shared memory does not exist, create it
		if (!sharedMemory.create(DEFAULT_MEMORY_SIZE, QSharedMemory::ReadWrite)) {
			QSharedMemory::SharedMemoryError err = sharedMemory.error();

			IS_INIT = XFALSE;
		}
		else {
			sharedMemory.lock();
			cleanMemory();
			sharedMemory.unlock();
			
			read_cfg_file();

			writeToMemory();

			//QMessageBox::information(0,"Success",QStringEx::fromLocal8Bit("读取文件成功"));
			qDebug()<<QStringEx::fromLocal8Bit("ReadCfgSuccess!");
			IS_INIT = XTRUE;
		}
	}
	else
	{ 
		if (isForceRefresh)
		{
			sharedMemory.lock();
			cleanMemory();
			sharedMemory.unlock();

			read_cfg_file();

			writeToMemory();

			//QMessageBox::information(0,"Success",QStringEx::fromLocal8Bit("强制刷新内存成功"));
			qDebug()<<QStringEx::fromLocal8Bit("FroceRefreshMemorySuccess!");
			IS_INIT = XTRUE;
		}
		else
		{
			readFromMemory();
			IS_INIT = XTRUE;
		}
	}
}

bool DirMgr::isMemoryClear()
{
	// Lock shared memory
	sharedMemory.lock();
	// Read from memory
	QByteArray newData = QByteArray((char*) sharedMemory.constData(), sharedMemory.size());
	// Unlock shared memory
	sharedMemory.unlock();

	QString message = QString::fromUtf8(newData.constData());
	//    qDebug() << message;
	if (message.length() != 0)
	{
		sharedMemory.lock();
		cleanMemory();
		sharedMemory.unlock();
	}
	return true;
}

void DirMgr::writeToMemory()
{
	QString writedata="";
	for(XINT i=0;i<SYSTEM_DIR_NSA3000T_MAXCOUNT;i++)
	{
		if (i==SYSTEM_DIR_NSA3000T_MAXCOUNT-1)
		{
			writedata += QString::fromLocal8Bit(P_SYSTEM_DIR_EN_STR[i]);
		}
		else
		{
			writedata += QString::fromLocal8Bit(P_SYSTEM_DIR_EN_STR[i])+";";
		}
	}
	if (isMemoryClear()) 
	{
		// Shared memory is clear and we write data into it
		sharedMemory.lock();
		char *to = (char*) sharedMemory.data();
		const char *from = writedata.toLocal8Bit().data();
		memcpy(to, from, writedata.toLocal8Bit().size());
		sharedMemory.unlock();
	}
}

void DirMgr::readFromMemory()
{
	// Lock shared memory
	sharedMemory.lock();
	// Read from memory
	QByteArray newData = QByteArray((char*) sharedMemory.constData(), sharedMemory.size());
	// Unlock shared memory
	sharedMemory.unlock();

	QString message = QString::fromLocal8Bit(newData.constData());
	//    qDebug() << message;
	if (message != "")
	{
		QStringList en_dir_temp_list=message.split(";");
		for(XINT i=0;i<en_dir_temp_list.count();i++)
		{
			if (en_dir_temp_list.at(i) != "")
			{
				sprintf(P_SYSTEM_DIR_EN_STR[i],en_dir_temp_list.at(i).toLocal8Bit().data());
			}
		}

		//QMessageBox::information(0,"Success",QStringEx::fromLocal8Bit("读取内存成功"));
		qDebug()<<QStringEx::fromLocal8Bit("ReadMemorySuccess!");
	}
	else
	{
		//QMessageBox::information(0,"Fail",QStringEx::fromLocal8Bit("读取内存失败，转为文件读取"));
		qDebug()<<QStringEx::fromLocal8Bit("ReadMemoryFail,ChangeToReadCfg!");
		read_cfg_file();
		writeToMemory();
	}

}

void DirMgr::cleanMemory()
{  
	memset(sharedMemory.data(), 0, sharedMemory.size());
}